package be.ipl.vingtetun.usecasesimpl;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import be.ipl.vingtetun.dao.JoueurDao;
import be.ipl.vingtetun.dao.PartieDao;
import be.ipl.vingtetun.domaine.De;
import be.ipl.vingtetun.domaine.Joueur;
import be.ipl.vingtetun.domaine.Partie;
import be.ipl.vingtetun.domaine.Partie.Etat;
import be.ipl.vingtetun.usecases.GestionPartie;

@Singleton
@Startup
public class GestionPartieImpl implements GestionPartie {
	private Partie partie;
	private static int num = 0;

	@EJB
	JoueurDao joueurDao;
	@EJB
	PartieDao partieDao;

	@Override
	public boolean rejoindreLaPartie(String pseudo) {
		if (partie != null && partie.getEtat() == Etat.EN_COURS)
			return false;
		if (partie == null || partie.getEtat() == Etat.FINIE) {
			partie = new Partie("partie" + num);
			num++;
			partie = partieDao.enregistrer(partie);
		}

		partie = partieDao.rechercher(partie.getId());

		Joueur joueur = joueurDao.rechercher(pseudo);
		if (joueur == null) {
			joueur = new Joueur(pseudo);
			joueur = joueurDao.enregistrer(joueur);
		}
		return partie.ajouterJoueur(joueur);

	}

	@Override
	@Lock(LockType.READ)
	public List<String> listerJoueurs() {
		if (partie == null)
			return null;
		List<Joueur> js = partie.getJoueurs();
		List<String> pseudos = new ArrayList<String>();
		for (Joueur j : js)
			pseudos.add(j.getPseudo());
		return pseudos;
	}

	@Override
	public boolean commencerPartie() {
		if (partie == null || partie.getEtat() != Etat.INITIAL)
			return false;
		partie = partieDao.rechercher(partie.getId());
		return partie.commencerPartie();
	}

	@Override
	@Lock(LockType.READ)
	public String joueurCourant() {
		if (partie == null)
			return null;
		if (partie.getJoueurCourant() == null)
			return null;
		return partie.getJoueurCourant().getPseudo();
	}

	@Override
	@Lock(LockType.READ)
	public List<De> listerDesJoues() {
		if (partie == null)
			return null;
		partie = partieDao.rechercher(partie.getId());
		List<De> liste = new ArrayList<De>();
		liste.addAll(partie.getDesJouables());
		return liste;
	}

	@Override
	public int lancerLesDes() {
		if (partie == null)
			return 0;
		partie = partieDao.rechercher(partie.getId());
		return partie.lancerLesDes();
	}

	@Override
	public boolean ecarterDe(int numero) {
		if (partie == null)
			return false;
		partie = partieDao.rechercher(partie.getId());
		boolean result = partie.ecarterDe(numero);
		return result;
	}

	@Override
	@Lock(LockType.READ)
	public int mesPoints() {
		if (partie == null)
			return 0;
		partie = partieDao.rechercher(partie.getId());
		return partie.getPoints(partie.getJoueurCourant());
	}

	@Override
	@Lock(LockType.READ)
	public int points(String pseudo) {
		if (partie == null)
			return 0;
		partie = partieDao.rechercher(partie.getId());
		return partie.getPoints(partie.getJoueur(pseudo));
	}

	@Override
	public boolean auSuivant() {
		if (partie == null)
			return false;
		partie = partieDao.rechercher(partie.getId());
		return partie.commencerTourSuivant();

	}

	@Override
	public String vainqueur() {
		if (partie == null)
			return null;
		partie = partieDao.rechercher(partie.getId());
		Joueur v = partie.estVainqueur();
		if (v == null)
			return null;
		return v.getPseudo();
	}

	@Override
	public boolean estFinie() {
		if (partie == null)
			return true;
		partie = partieDao.rechercher(partie.getId());
		return partie.getEtat() == Etat.FINIE;
	}

	@Override
	public void annulerPartie() {
		if (partie != null)
			partie.annuler();
	}

}
